package org.rebluh.hulunbuirtravelnetworkbackendframework.service;

import org.rebluh.hulunbuirtravelnetworkbackendframework.domain.Hulber;
import org.rebluh.hulunbuirtravelnetworkbackendframework.domain.Image;
import org.rebluh.hulunbuirtravelnetworkbackendframework.dto.HulberImagesDTO;
import org.rebluh.hulunbuirtravelnetworkbackendframework.repository.HulberRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class HulberService {
    @Autowired
    private HulberRepository hulberRepository;
    @Autowired
    private MongoTemplate mongoTemplate;

    //添加景点
    public Hulber createHulber(Hulber hulber) {
        return hulberRepository.save(hulber);
    }

    //根据id获取景点
    public Optional<Hulber> getHulberById(String id) {
        return hulberRepository.findById(id);
    }

    //获取全部景点
    public List<Hulber> getAllHulber() {
        return hulberRepository.findAll();
    }

    //根据区域查询景区
    public List<HulberImagesDTO> getHulberImagesByKey(String key) {
        Aggregation aggregation;
        if (key.equals("呼伦贝尔")){
            //获取全部数据
            ProjectionOperation projectionOperation = Aggregation.project()
                .and("_id").as("id")
                .and("name").as("name")
                .and("star").as("star")
                .and("region").as("region")
                .and("openDate").as("openDate")
                .and("openTime").as("openTime")
                .and("ticket").as("ticket");
            aggregation = Aggregation.newAggregation(
                    projectionOperation
            );
        } else if (key.equals("随便看看")) {
            //随机取10-20条的数据
            Random random = new Random();
            int min = 10;
            int max = 20;
            int randomCount = random.nextInt((max - min) + 1) + min;
            ProjectionOperation projectionOperation = Aggregation.project()
                    .and("_id").as("id")
                    .and("name").as("name")
                    .and("star").as("star")
                    .and("region").as("region")
                    .and("openDate").as("openDate")
                    .and("openTime").as("openTime")
                    .and("ticket").as("ticket");
            SampleOperation sampleOperation = Aggregation.sample(randomCount);
            aggregation = Aggregation.newAggregation(
                    projectionOperation,
                    sampleOperation
            );
        }else{
            //获取指定地区的数据
            ProjectionOperation projectionOperation = Aggregation.project()
                    .and("_id").as("id")
                    .and("name").as("name")
                    .and("star").as("star")
                    .and("region").as("region")
                    .and("openDate").as("openDate")
                    .and("openTime").as("openTime")
                    .and("ticket").as("ticket");
            MatchOperation matchOperation = Aggregation.match(Criteria.where("region").is(key));
            aggregation = Aggregation.newAggregation(
                    projectionOperation,
                    matchOperation
            );
        }
//        aggregation = Aggregation.newAggregation(
//                    Aggregation.lookup("image","id","toHulberId","imageDetails"),
//                    Aggregation.project("id","name","star","region","openDate","openTime","ticket","imageDetails")
//            );
//
//         Match documents in Hulber collection by region
//        MatchOperation matchOperation = Aggregation.match(Criteria.where("region").is(key));
//
//        // Lookup operation to join Hulber and Image collections
//        LookupOperation lookupOperation = Aggregation.lookup("image", "id", "toHulberId", "imageDetails");
//
//        // Unwind the imageDetails array
//        UnwindOperation unwindOperation = Aggregation.unwind("imageDetails");
//
//        // Sort imageDetails by position in ascending order
//        SortOperation sortOperation = Aggregation.sort(Sort.by(Sort.Order.asc("imageDetails.position")));
//
//        // Group by Hulber fields and push image details into an array
//        GroupOperation groupOperation = Aggregation.group("id", "name", "star", "region", "openDate", "openTime", "ticket")
//                .first("id").as("id")
//                .first("name").as("name")
//                .first("star").as("star")
//                .first("region").as("region")
//                .first("openDate").as("openDate")
//                .first("openTime").as("openTime")
//                .first("ticket").as("ticket")
//                .push("imageDetails").as("imageDetails");
//
//        // Project the required fields and limit the imageDetails to 5
//        ProjectionOperation projectOperation = Aggregation.project("id", "name", "star", "region", "openDate", "openTime", "ticket")
//                .andExpression("slice(imageDetails, 5)").as("imageDetails");
//
//        // Create the aggregation pipeline
//        Aggregation aggregation = Aggregation.newAggregation(
//                matchOperation,
//                lookupOperation,
//                unwindOperation,
//                sortOperation,
//                groupOperation,
//                projectOperation
//        );

        AggregationResults<HulberImagesDTO> results = mongoTemplate.aggregate(
                aggregation, "hulber", HulberImagesDTO.class);

        //添加图片
        List<HulberImagesDTO> list = results.getMappedResults();
        for (HulberImagesDTO dto : list) {
            List<Image> img = mongoTemplate.find(Query.query(Criteria.where("toHulberId").is(dto.getId())), Image.class);
            List<HulberImagesDTO.ImageDetails> imageDetailsList = new ArrayList<>();
            int i = 0;
            for (Image image : img){
                HulberImagesDTO.ImageDetails imageDetails = new HulberImagesDTO.ImageDetails(image.getId(),image.getSmallImg());
                imageDetailsList.add(imageDetails);
                i ++;
                if (i == 5) break;
            }
            dto.setImageDetails(imageDetailsList);
        }
        return list;
    }
}
